<?php
App::uses('Component', 'Controller');
class Sudoku2Component extends Component {
	public function checkSudoku($sudoku){
		$listArrRow = array();
		$listArrCol = array();
		$listArrBlock = array();
		$arrayWidth = count($sudoku[0]);
		$blockwidth = sqrt($arrayWidth);
// 		print_r($blockwidth);
// 		exit;
		
// 		if($this->hasDuplicateInArray($arrayWidth) == true){
// 			$result = "1";
// 		}else{
// 			$result = "2";
// 		}
// 		print_r($result);
// 		exit;
		
		for($i=0; $i<$arrayWidth; $i++){ //row
			$arrCol = array();
			array_push($listArrRow, $sudoku[$i]);
			$check = $this->checkArrayValid($sudoku[$i]);
			if($check != "Valid"){
				return $check.", row ".$i; 
			}
			for($j=0; $j<$arrayWidth; $j++){ //column
				array_push($arrCol, $sudoku[$j][$i]);
				
				
				$keyOfBlock = floor($i/$blockwidth).floor($j/$blockwidth) ;
				
				if(!array_key_exists($keyOfBlock, $listArrBlock)){
					$listArrBlock[$keyOfBlock] = array();
				}
				array_push($listArrBlock[$keyOfBlock], $sudoku[$i][$j]);
			}
			array_push($listArrCol, $arrCol);
			$check = $this->checkArrayValid($arrCol);
			if($check != "Valid"){
				return $check.", column ".$i;
			}
		}
		
		$check = $this->checkArrayBlockValid($listArrBlock);
		if($check != "Valid"){
			return $check;
		}
		
		return "Valid";
		
// 		print_r($listArrBlock['00']);
// 		exit;
		
	}
	
	
	/**
	 * 
	 * @param array to check $arrayRow
	 * @return "Valid" if not have any error, else, return error and error position
	 */
	private function checkArrayValid($arrayRow){
// 		return "abc";
		if(!is_int($arrayRow[0])){
			return "Has not int at position 0";
		}
		if($arrayRow[0] < 1 || $arrayRow[0] > 9){
			return "Has not 1-9 value at position 0";			
		}
		
		for($i=0; $i<count($arrayRow)-1; $i++){
			if(!is_int($arrayRow[$i+1])){
				return "Has not int at position ".$i;
			}
			if($arrayRow[$i] < 1 || $arrayRow[$i] > 9){
				return "Has not 1-9 value at position ".$i;
			}
			
			for($j=$i+1; $j<count($arrayRow); $j++){
				if($arrayRow[$i] == $arrayRow[$j]){
					return "Has duplicate value at position ".$i." and ".$j;
				}
			}
		}
		return "Valid";
	}
	
	private function checkArrayBlockValid($listArrayBlock){
		foreach ($listArrayBlock as $key => $arrayBlock){
			$check = $this->checkArrayValid2($arrayBlock);
			if($check != "Valid"){
				return $check.", array ".$key;
			}
		}
		return "Valid";
	}
	
	
	public function checkSudoku2($sudoku){
		$listArrRow = array();
		$listArrCol = array();
		$listArrBlock = array();
		$arrayWidth = count($sudoku[0]);
		$blockwidth = sqrt($arrayWidth);
	
		for($i=0; $i<$arrayWidth; $i++){ //row
			$arrCol = array();
			array_push($listArrRow, $sudoku[$i]);
			$check = $this->checkArrayValid2($sudoku[$i]);
			echo "$check <br/>";
			if($check != "Valid"){
				return $check.", row ".$i;
			}
			for($j=0; $j<$arrayWidth; $j++){ //column
				array_push($arrCol, $sudoku[$j][$i]);
	
// 				print_r($listArrBlock);
				$keyOfBlock = $blockwidth*floor($i/$blockwidth) + floor($j/$blockwidth); 
// 				print_r(count($listArrBlock[$keyOfBlock]));
// 				exit;
				
	
				if(!array_key_exists("$keyOfBlock", $listArrBlock)){
					$listArrBlock[$keyOfBlock] = array();
				}
				array_push($listArrBlock[$keyOfBlock], $sudoku[$i][$j]);
			}
			array_push($listArrCol, $arrCol);
			$check = $this->checkArrayValid2($arrCol);
			if($check != "Valid"){
				return $check.", column ".$i;
			}
		}
		
// 		print_r($listArrBlock);
// 		exit;
	
		$check = $this->checkArrayBlockValid($listArrBlock);
		if($check != "Valid"){
			return $check;
		}
	
		return "Valid";
	
		// 		print_r($listArrBlock['00']);
		// 		exit;
	
	}
	
	private function checkArrayValid2($array){
		
		//array size != 9
		if(count($array) != 9){
			return "Not 9 item";
		}
		
		$abc = function ($var){
			if(is_int($var)){
				return $var;
			}
			return '';
		};
		
		//
		if(count(array_filter($array, $abc)) != 9){
			return "Has string";
		}
		
		//array after remove duplicate value size != 9 
		if(count(array_unique($array)) != 9){
			return "Has duplicate";
		}
		
		//if array have max value > 9
		if(max($array) > 9){
			return "Max value > 9";
		}
		
		//if array have min value < 1
		if(min($array) < 1){
			return "Min value < 1";
		}
		return "Valid";
	}
}